﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AAA.Meta.Quote.Data
{
#if !SILVERLIGHT
    [Serializable]
#endif
    public class BarRecord
    {
        public const string OPEN = "Open";
        public const string HIGH = "High";
        public const string LOW = "Low";
        public const string CLOSE = "Close";
        public const string VOLUME = "Volume";
        public const string AMOUNT = "Amount";
        public const string YESTERDAY_CLOSE = "YesterdayClose";

        private string _strSymbolId;
        private DateTime _barDateTime;
        private BarCompressionEnum _enumBarCompression = BarCompressionEnum.Min_1;
        private int _iInterval;
        private List<object> _lstValue;
        private List<string> _lstParamName;

        public BarRecord()
        {
            _lstValue = new List<object>();
            _lstParamName = new List<string>();
        }

        public string SymbolId
        {
            get { return _strSymbolId; }
            set { _strSymbolId = value; }
        }

        public DateTime BarDateTime
        {
            get { return _barDateTime; }
            set { _barDateTime = value; }
        }

        public BarCompressionEnum BarCompression
        {
            get { return _enumBarCompression; }
            set { _enumBarCompression = value; }
        }

        public BarRecord Clone()
        {
            BarRecord barReturn = new BarRecord()
            {
                SymbolId = this.SymbolId,
                BarDateTime = this.BarDateTime,
                BarCompression = this.BarCompression,
                CompressionInterval = this.CompressionInterval
            };

            foreach (string strName in GetParamNames())
                barReturn[strName] = this[strName];

            return barReturn;
        }

        public List<string> GetParamNames()
        {
            List<string> lstField = new List<string>();
            try
            {
                foreach(string strParamName in _lstParamName)
                    lstField.Add(ReverseName(strParamName));
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return lstField;
        }

        public int CompressionInterval
        {
            get { return _iInterval; }
            set { _iInterval = value; }
        }

        private string SwitchName(string strName)
        {
            switch (strName)
            {
                case OPEN:
                    strName = "V0";
                    break;

                case HIGH:
                    strName = "V1";
                    break;

                case LOW:
                    strName = "V2";
                    break;

                case CLOSE:
                    strName = "V3";
                    break;

                case VOLUME:
                    strName = "V4";
                    break;

                case AMOUNT:
                    strName = "V5";
                    break;            
            }
            return strName;
        }

        private string ReverseName(string strName)
        {
            switch (strName)
            {
                case "V0":
                    strName = OPEN;
                    break;

                case "V1":
                    strName = HIGH;
                    break;

                case "V2":
                    strName = LOW;
                    break;

                case "V3":
                    strName = CLOSE;
                    break;

                case "V4":
                    strName = VOLUME;
                    break;

                case "V5":
                    strName = AMOUNT;
                    break;            
            }
            return strName;
        }

        public float this[string strName]
        {
            get
            {
                return _lstParamName.IndexOf(SwitchName(strName)) < 0 ? float.NaN : this[_lstParamName.IndexOf(SwitchName(strName))];
            }

            set
            {
                if (_lstParamName.IndexOf(SwitchName(strName)) < 0)
                {
                    _lstParamName.Add(SwitchName(strName));
                    _lstValue.Add(value);
                    return;
                }

                this[_lstParamName.IndexOf(SwitchName(strName))] = value;
            }
        }

        public float this[int iIndex]
        {
            get
            {
                return (iIndex < _lstValue.Count) && (iIndex >= 0) ? (float)_lstValue[iIndex] : float.NaN;
            }

            set
            {
                _lstValue[iIndex] = value;
            }
        }

        public void Update(BarRecord barRecord)
        {
            int iVariableIndex;
            for (int i = 0; i < barRecord._lstParamName.Count; i++)
            {
                if((iVariableIndex = _lstParamName.IndexOf(barRecord._lstParamName[i])) >= 0)
                {
                    _lstValue[iVariableIndex] = barRecord._lstValue[i];
                }
                else
                {
                    _lstParamName.Add(barRecord._lstParamName[i]);
                    _lstValue.Add(barRecord._lstValue[i]);
                }
            }
        }

        public float V0
        {
            get { return this["V0"]; }
            set { this["V0"] = value; }
        }

        public float V1
        {
            get { return this["V1"]; }
            set { this["V1"] = value; }
        }

        public float V2
        {
            get { return this["V2"]; }
            set { this["V2"] = value; }
        }

        public float V3
        {
            get { return this["V3"]; }
            set { this["V3"] = value; }
        }

        public float V4
        {
            get { return this["V4"]; }
            set { this["V4"] = value; }
        }

        public float V5
        {
            get { return this["V5"]; }
            set { this["V5"] = value; }
        }
    }
}
